﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

using RRRSRoguelike.Enums;
using RRRSRoguelike.Screens;
using RRRSRoguelikeData;

namespace RRRSRoguelike.Managers
{
    /// <summary>
    /// Manages the game flow.
    /// </summary>
    class GameManager
    {

        #region variables
        
        /// <summary>
        /// Time passed 
        /// </summary>
        public Stopwatch Time;
        
        /// <summary>
        ///Game time per dungeon
        /// </summary>
        public Stopwatch GameTime;
        
        /// <summary>
        /// A list of stopwatches for general use.
        /// </summary>
        public Dictionary<string,Stopwatch> StopWatches = new Dictionary<string,Stopwatch>();
        
        /// <summary>
        /// A basic screen manager 
        /// </summary>
        public Stack<Screen> ScreenStack = new Stack<Screen>();
        
        /// <summary>
        /// keeps a lost of all texts to be used in game menus outside of a dungeon instance
        /// </summary>
        public Dictionary<string, string> Texts = new Dictionary<string, string>();
		
        /// <summary>
        /// handles all input
        /// </summary>
		public InputManager InputManager;
        
        /// <summary>
        /// handles sound outside of a dungeon instance
        /// </summary>
        public SoundManager SoundManager;

        #endregion

        #region singleton
        static readonly GameManager instance = new GameManager();

        public static GameManager Instance
        {
            get { return instance; }
        }
        #endregion

        #region methods
        /// <summary>
        /// Initializes the gameScreens.
        /// </summary>
        private void Initialize() 
        {
        	InitializeManagers();
            
            LoadContent(); 
			
            SetupTime();
            
            SetupScreens();
        }
		
        void InitializeManagers()
        {
        	GameManager.Instance.SoundManager = new SoundManager();
            
            GameManager.Instance.InputManager = new InputManager();
        }
        
        void LoadContent()
        {
        	Texts.Add("Splash", Files.TxtFileToString("Content/Texts/Splash.txt"));
            Texts.Add("Credits", Files.TxtFileToString("Content/Texts/Credits.txt"));
            GameManager.Instance.SoundManager.AddSound("Pluck", "Content/Sound/Pluck.wav");
        }
        
        void SetupTime()
        {
        	Time = new Stopwatch();
            Time.Start();
            GameTime = new Stopwatch();
        }
        
        /// <summary>
        ///Used to design game flow.
        ///Splash and menu screens come off the stack first, credit remains until exit, with no screens pushed on top.  
        /// </summary>
        void SetupScreens()
        {	
            //Last screen goes in first
        	ScreenStack.Push(new TextScreen(Texts["Credits"]));
            
        	//The menu screen will leave the stack and then push new screens here according to user input.
            ScreenStack.Push(new MenuScreen());
            
            //Splash will be the first screen to leave the stack and be displayed to the user.
            ScreenStack.Push(new TextScreen(Texts["Splash"]));
        }
        
        /// <summary>
        /// Entry point. Controls the gameflow.
        /// </summary>
        public void Run()
        {            
            Initialize();

            //This is the main engine or loop of the game and calls screens one by one to show to the user.
            while (ScreenStack.Count>0)
                ScreenStack.Pop().Show();
        }

        public void ChangeAnimSpeed()
		{
			Properties.Settings.Default.AnimationSpeed -= 10;
                if (Properties.Settings.Default.AnimationSpeed < 10)
                    Properties.Settings.Default.AnimationSpeed = 100;

                Properties.Settings.Default.Save();

                SoundManager.PlaySound(SoundList.Pluck.ToString());
		}
        
		public bool ToggleSetting(bool toggle)
		{
			//Toggle
                if (toggle)
                    toggle = false;
                else
                    toggle = true;
                                
                return toggle;
		}
        
        public void Exit()
        {
            //Exit console
        	Environment.Exit(0);
        }

        #endregion

    }
}
